'''
Created on Sep 7, 2012

@author: petrina
'''
from link_indicator import Link_indicator
import logging

class Mean_squared_error(Link_indicator):
    '''
    Calculates the mean squared error for every time interval (using aggregated fcd-data).
    
    Formula for calculating the indicator: 
        mse_i = 1/N * sum((ye_i_d - y0_i_d)^2 )
            where:
                - mse_i  ... mean squared error on the time interval i 
                - N  ... number of days  
                - ye_i_d ... expected/measured data on the time interval i and day d
                - y0_i_d ... reference data on the time interval i and day d 
                
    
    unit: index value
    '''


    def __init__(self, link):
        '''        
        @param link: Link-object (containing valid records and reference) 
        '''
        
        Link_indicator.__init__(self, link)
        
        self._name = 'Mean Squared Error'
        self._mr_name = 'mse'
        self._unit = 'index'
        #self.unit.__doc__ = 'index value'

        self._create_title(link.id, link.direction)
        
        logging.debug("Mean_squared_error: created new Mean_squared_error")
        
    #----------------------public methods of the class-------------------------

        
    def calculate(self):
        '''
        @return: values for the mean squared error for every time interval as list of Result_values
        '''
        
        logging.info("Mean_squared_error: staring to calculate the mean squared error")
                
        values = []
        
        # for all intervals
        for i in range(self._intervals):
            ref_data = self._link.reference[i]
            rec_data = self._link.records[i]

            
            value = None
            if len(ref_data) > 0 and len(rec_data) > 0:            
                min_time = min(rec_data.begintime, ref_data.begintime)
                max_time = max(rec_data.endtime, ref_data.endtime)
                
                ye = rec_data.create_value_list(min_time, max_time, attribute = 'speed') 
                y0 = ref_data.create_value_list(min_time, max_time, attribute = 'speed') 
                    
                sum_diff = 0    
                n = 0
                # for every day
                for j in range(len(ye)):           
                    if ye[j] is not None and y0[j] is not None:
                        sum_diff += ((ye[j] - y0[j]) * (ye[j] - y0[j]))
                        n += 1
                    
                if n > 0:
                    value = sum_diff/n
                
            values.append(value)
        
        
        self._values = values

        logging.debug("Mean_squared_error : finished calculating the mean squared error")

        return self._values